home *** CD-ROM | disk | FTP | other *** search
/ Sprite 1984 - 1993 / Sprite 1984 - 1993.iso / src / kernel / dev / sun4.md / devGraphics.c < prev    next >
C/C++ Source or Header  |  1992-12-18  |  34KB  |  1,230 lines

  1. /* 
  2.  * devGraphics.c --
  3.  *
  4.  *    This module provides frame buffer device support.
  5.  *
  6.  * Copyright 1989 Regents of the University of California
  7.  * Permission to use, copy, modify, and distribute this
  8.  * software and its documentation for any purpose and without
  9.  * fee is hereby granted, provided that the above copyright
  10.  * notice appear in all copies.  The University of California
  11.  * makes no representations about the suitability of this
  12.  * software for any purpose.  It is provided "as is" without
  13.  * express or implied warranty.
  14.  */
  15.  
  16. #ifndef lint
  17. static char rcsid[] = "$Header: /cdrom/src/kernel/Cvsroot/kernel/dev/sun4.md/devGraphics.c,v 1.12 91/10/18 01:21:04 dlong Exp $ SPRITE (Berkeley)";
  18. #endif /* not lint */
  19.  
  20. #include "sprite.h"
  21. #include "dev.h"
  22. #include <sys/ioctl.h>
  23. #include "devfb.h"
  24. #include "fs.h"
  25. #include "vmMach.h"
  26. #include "rpc.h"
  27. #include "stdio.h"
  28. #include "sys/types.h"
  29. #include "mon/eeprom.h"
  30. #include "machMon.h"
  31. #include "stdlib.h"
  32. #include "string.h"
  33. #include "bstring.h"
  34. #include "alloca.h"
  35.  
  36. #define EEC_COLOR_TYPE_CG4      4       /* missing in mon/eeprom.h */
  37. #define EEC_COLOR_TYPE_CG6      6       /* missing in mon/eeprom.h */
  38.  
  39. /*
  40.  * For BW2 frame buffer
  41.  */
  42.  
  43.  
  44. #ifdef sun3
  45. #define BW2_FB    ((Address) 0x0fe20000)
  46. #elif sun4c
  47. #define BW2_FB    ((Address) NIL)
  48. #elif sun4
  49. #define BW2_FB    ((Address) 0xffd40000)
  50. #else
  51. #define    BW2_FB    ((Address) NIL)
  52. #endif /* sun3 */
  53.  
  54.  
  55. /*
  56.  * For CG4 frame buffer
  57.  */
  58. #ifdef sun3
  59. #define CG4_FB     ((Address) 0x0fd00000)
  60. #define CG4_CM     ((Address) 0x0fe0e000)
  61. #define CG4_OV     ((Address) 0x0fe80000)
  62. #define CG4_EN     ((Address) 0x0fea0000)
  63. #else
  64. #define CG4_FB    ((Address) NIL)
  65. #define CG4_CM    ((Address) NIL)
  66. #define CG4_OV    ((Address) NIL)
  67. #define CG4_EN    ((Address) NIL)
  68. #endif /* sun3 */
  69. /*
  70.  * For CG6 frame buffer
  71.  */
  72. #define CG6_FB    ((Address) NIL)
  73. #define CG6_CM    ((Address) NIL)
  74. /*
  75.  * CG3 frame buffer.
  76.  */
  77. #define CG3_FB    ((Address) NIL)
  78. #define CG3_CM    ((Address) NIL)
  79.  
  80.  
  81. typedef    struct    FBDevice {
  82.     FBType    type;
  83.     FBInfo    info;
  84.     FBCMap    cmap;
  85. } FBDevice;
  86.  
  87. /*
  88.  * Associates a string with each fb type so we can use a hack to look up
  89.  * the type per machine from a file rather than the prom...
  90.  */
  91. char    *fbNames[FBTYPE_LASTPLUSONE] = {
  92.     "bwone",
  93.     "cgone",
  94.     "bwtwo",
  95.     "cgtwo",
  96.     "FBTYPE_SUN_GP2",
  97.     "FBTYPE_SUN_CG5",
  98.     "cgthree",
  99.     "FBTYPE_MEMCOLOR",
  100.     "cgfour",
  101.     "FBTYPE_NOTSUN1",
  102.     "FBTYPE_NOTSUN2",
  103.     "FBTYPE_NOTSUN3",
  104.     "cgsix",
  105.     "FBTYPE_SUNROP_COLOR",
  106.     "FBTYPE_SUNFB_VIDEO",
  107.     "FBTYPE_RESERVED5",
  108.     "FBTYPE_RESERVED4",
  109.     "FBTYPE_RESERVED3",
  110.     "FBTYPE_RESERVED2",
  111.     "FBTYPE_RESERVED1"
  112. };
  113.  
  114. /*
  115.  * Brooktree DAC
  116.  */
  117. volatile struct colormap {
  118.     unsigned int    addr;        /* colormap address register */
  119.     unsigned int    cmap;        /* colormap data register */
  120.     unsigned int    ctrl;        /* control register */
  121.     unsigned int    omap;        /* overlay map data register */
  122. } *fbCmap = (volatile struct colormap *) NIL;
  123.  
  124. /* Copy of colormap (for CG4 only!) */
  125. static union {
  126.         unsigned char   map[256][3];    /* reasonable way to access */
  127.         unsigned int    raw[256*3/4];   /* unreasonable way used to load h/w */
  128. } fbCmapCopy;
  129.  
  130.  
  131. /*
  132.  * Addresses to know for the different frame buffers, overlay planes, etc.
  133.  */
  134. typedef    struct FBAddr {
  135.     Address    fb_buffer;        /* kernel virtual address */
  136.     Address    fb_overlay;        /* offset? */
  137.     Address    fb_enable;        /* offset? */
  138.     Address    fb_cmap;        /* cmap */
  139. } FBAddr;
  140.  
  141. /*
  142.  * Addresses for frame buffer, overlay and enable.  This is in a separate
  143.  * array since it's different per machine type.  I only have it for
  144.  * one machine type right now (sun4c).
  145.  */
  146. FBAddr    fbaddrs[FBTYPE_LASTPLUSONE] = {
  147.     {(Address) NIL, (Address) NIL, (Address) NIL, (Address) NIL}, /* bw1 */
  148.     {(Address) NIL, (Address) NIL, (Address) NIL, (Address) NIL}, /* cg1 */
  149.     {BW2_FB, (Address) NIL, (Address) NIL, (Address) NIL},      /* bw2 */
  150.     {(Address) NIL, (Address) NIL, (Address) NIL, (Address) NIL}, /* cg2 */
  151.     {(Address) NIL, (Address) NIL, (Address) NIL, (Address) NIL}, /* gp2 */
  152.     {(Address) NIL, (Address) NIL, (Address) NIL, (Address) NIL}, /* cg5 */
  153.     {CG3_FB, (Address) NIL, (Address) NIL, CG3_CM},          /* cg3 */
  154.     {(Address) NIL, (Address) NIL, (Address) NIL, (Address) NIL}, /* ? */
  155.     {CG4_FB, CG4_OV, CG4_EN, CG4_CM},                  /* cg4 */
  156.     {(Address) NIL, (Address) NIL, (Address) NIL, (Address) NIL}, /* cust. */
  157.     {(Address) NIL, (Address) NIL, (Address) NIL, (Address) NIL}, /* cust. */
  158.     {(Address) NIL, (Address) NIL, (Address) NIL, (Address) NIL}, /* cust. */
  159.     {CG6_FB, (Address) NIL, (Address) NIL, CG6_CM},          /* cg6 */
  160.     {(Address) NIL, (Address) NIL, (Address) NIL, (Address) NIL}, /* rop */
  161.     {(Address) NIL, (Address) NIL, (Address) NIL, (Address) NIL}, /* video */
  162.     {(Address) NIL, (Address) NIL, (Address) NIL, (Address) NIL}, /* res5 */
  163.     {(Address) NIL, (Address) NIL, (Address) NIL, (Address) NIL}, /* res4 */
  164.     {(Address) NIL, (Address) NIL, (Address) NIL, (Address) NIL}, /* res3 */
  165.     {(Address) NIL, (Address) NIL, (Address) NIL, (Address) NIL}, /* res2 */
  166.     {(Address) NIL, (Address) NIL, (Address) NIL, (Address) NIL}  /* res1 */
  167. };
  168.  
  169.  
  170. /*
  171.  * For convenience we store info about the frame buffer types here.  If we
  172.  * get the info from the prom, we overwrite the stuff here.
  173.  * Array indexed by fb_type, found in fb.h.
  174.  * An example of what would be overwritten is if we have a high resolution
  175.  * b&w screen, the info in the prom will give us
  176.  *    {high resolution bw2, 1280, 1600, 1, 2, 256*1024},    (* bw2h *)
  177.  * instead of the regular bw2.  Also, for cg3, we could have a second type:
  178.  *    {cg3b, 768, 1024, -1, -1, -1}             (* cg3 B *)
  179.  */
  180.         /* type, height, width, depth, cmsize, size */
  181. FBType    fbarray[FBTYPE_LASTPLUSONE] = {
  182.     {FBTYPE_SUN1BW, -1, -1, -1, -1, -1},            /* bw1 */
  183.     {FBTYPE_SUN1COLOR, -1, -1, -1, -1, -1},            /* cg1 */
  184.     {FBTYPE_SUN2BW, 900, 1152, 1, 2, 128*1024},        /* bw2 */
  185.     {FBTYPE_SUN2COLOR, 900, 1152, 8, -1, -1},        /* cg2 */
  186.     {FBTYPE_SUN2GP, -1, -1, -1, -1, -1},            /* gp2 */
  187.     {FBTYPE_SUN5COLOR, -1, -1, -1, -1, -1},            /* cg5? |bw3? */
  188.     {FBTYPE_SUN3COLOR, 900, 1152, 8, 256, 1024*1024},    /* cg3 A */
  189.     {FBTYPE_MEMCOLOR, -1, -1, -1, -1, -1},            /* ? | bw4? */
  190.     {FBTYPE_SUN4COLOR, 900, 1152, 8, 256, 1024*1024},    /* cg4 */
  191.     {FBTYPE_NOTSUN1, -1, -1, -1, -1, -1},            /* customer */
  192.     {FBTYPE_NOTSUN2, -1, -1, -1, -1, -1},            /* customer */
  193.     {FBTYPE_NOTSUN3, -1, -1, -1, -1, -1},            /* customer */
  194.     {FBTYPE_SUNFAST_COLOR, 900, 1152, 8, 256, 1024*1024},    /* cg6=gx*/
  195.     {FBTYPE_SUNROP_COLOR, -1, -1, -1, -1, -1},
  196.     {FBTYPE_SUNFB_VIDEO, -1, -1, -1, -1, -1},
  197.     {FBTYPE_RESERVED5, -1, -1, -1, -1, -1},            /* don't use */
  198.     {FBTYPE_RESERVED4, -1, -1, -1, -1, -1},            /* don't use */
  199.     {FBTYPE_RESERVED3, -1, -1, -1, -1, -1},            /* don't use */
  200.     {FBTYPE_RESERVED2, -1, -1, -1, -1, -1},            /* don't use */
  201.     {FBTYPE_RESERVED1, -1, -1, -1, -1, -1}            /* don't use */
  202. };
  203.  
  204. /*
  205.  *
  206.  * Thorsten's notes for the old user-level fbio stuff:
  207.  *
  208.  *
  209.  * Brooktree DAC/colormap information
  210.  *
  211.  * Operation theory (really: guesses)
  212.  *
  213.  * The DAC has four byte size "ports" (cpu accessible registers) which have to
  214.  * be used to access the three internal register files with the 256 colormap
  215.  * RGB entries, a few control registers and 4 overlay RGB entries.
  216.  * To access a control register: write the register number (0-7?) into
  217.  * "addr" (see struct below), then write the value into "ctrl".
  218.  * To access a RGB entry: write the entry number (0-255 or 0-3) into "addr"
  219.  * then write the R, G and B values (in that order) into "cmap" or "omap".
  220.  * After the access, the "addr" is automatically incremented to allow quick
  221.  * updates of successive colormap entries.
  222.  *
  223.  * Now, this was the meat and here comes the spice:
  224.  * On the CG6 board, the ports are on (mod 4)=0 addresses and require
  225.  * longword accesses. This means the value has to go into bits 24-31 of
  226.  * an int which is then written to the chip. (Similarly for reading.)
  227.  * On the CG4 board, things are even better: the ports are on (mod 4)=3
  228.  * addresses and require longword accesses. The value can thus reside
  229.  * in the low 8 bits of an int. However, colormap RGB values behave
  230.  * wonderfully different: one longword write to "cmap" or "omap" is
  231.  * turned (by the hardware) into four byte writes to the chip, the
  232.  * top byte first, the bottom one last. (Dunno 'bout reads.) This means
  233.  * that one write to "cmap" or "omap" writes 4/3 colormap RGB entries.
  234.  * For example, writing a "1" into "addr" and 0x01020304 into "cmap" will
  235.  * set green and blue of color 1 to 0x01 and 0x02 resp. and will set
  236.  * red and green of color 2 to 0x03 and 0x04 resp.!
  237.  *
  238.  * Note: I didn't build these suckers, I just poked at them and guessed
  239.  * the behaviour, and I might be wrong...
  240.  *                      Thorsten von Eicken, 2/19/90
  241.  */
  242.  
  243. /*
  244.  * forward declarations for internal routines
  245.  */
  246. #ifdef sun4c
  247. static int CheckFBNode _ARGS_((unsigned int node, char *name));
  248. static int GetFBType _ARGS_((void));
  249. #endif
  250. static ReturnStatus PutCmap _ARGS_((int whichFb, FBCMap *cmap));
  251. static ReturnStatus GetCmap _ARGS_((int whichFb, FBCMap *cmap));
  252. static ReturnStatus SVideo _ARGS_((int whichFb, int *statePtr));
  253. static ReturnStatus GVideo _ARGS_((int whichFb, int *statePtr));
  254. static ReturnStatus InitCmap _ARGS_((FBDevice *devPtr));
  255.  
  256.  
  257.  
  258.  
  259. /*
  260.  *----------------------------------------------------------------------
  261.  *
  262.  * DevFBOpen --
  263.  *
  264.  *      Open the system frame buffer device.
  265.  *
  266.  * Results:
  267.  *      SUCCESS         - the device was opened.
  268.  *      FAILURE         - something went wrong.
  269.  *
  270.  * Side effects:
  271.  *      The device is opened.
  272.  *
  273.  *----------------------------------------------------------------------
  274.  */
  275. /*ARGSUSED*/
  276. ReturnStatus
  277. DevFBOpen(devicePtr, useFlags, token, flagsPtr)
  278.     Fs_Device    *devicePtr;    /* Device info, unit number, etc. */
  279.     int        useFlags;    /* Flags from the stream being opened. */
  280.     Fs_NotifyToken    token;    /* Call-back token for input, unused here. */
  281.     int        *flagsPtr;    /* OUT: Device open flags. */
  282. {
  283.     FBDevice        *devPtr;
  284. #ifdef sun4c
  285.     extern    int    GetFBType();
  286. #endif
  287.     FBType    *typePtr;
  288.     int        machArch;
  289.     int        machType;
  290.     int        whichFb = -1;
  291. #ifndef sun4c
  292.     struct    eeprom    *eeprom;
  293.     struct    eed_conf    *eeconf;
  294.     int        i;
  295. #endif
  296.  
  297.  
  298.     devPtr = (FBDevice *) malloc(sizeof (FBDevice));
  299.     bzero((char *) devPtr, sizeof (FBDevice));
  300.  
  301.     machArch = Mach_GetMachineArch();
  302.     machType = Mach_GetMachineType();
  303.  
  304.     devPtr->type.fb_type = -1;
  305.  
  306. #ifdef sun4c
  307.     whichFb = GetFBType();
  308.     if (whichFb == -1) {
  309.     whichFb = FBTYPE_SUN2BW;
  310.     }
  311. #else
  312.     switch (machArch) {
  313.     case SYS_SUN4:
  314.     case SYS_SUN3:
  315.     eeprom = (struct eeprom *)EEPROM_BASE;
  316.     eeconf = &(eeprom->ee_diag.eed_conf[0]);
  317.     for (i = 0; i < MAX_SLOTS; i++, eeconf++) {
  318. #ifdef  FOOBAR
  319.         printf("card type %d\n", eeconf->eec_un.eec_type);
  320. #endif  FOOBAR
  321.         /* end of card cage? */
  322.         if (eeconf->eec_un.eec_type == EEC_TYPE_END) {
  323.         break;
  324.         }
  325.         /* color display? */
  326.         if (eeconf->eec_un.eec_type == EEC_TYPE_COLOR) {
  327. #ifdef  FOOBAR
  328.         printf("\tcolor type %d\n",
  329.             eeconf->eec_un.eec_color.eec_color_type);
  330. #endif  FOOBAR
  331.         switch (eeconf->eec_un.eec_color.eec_color_type) {
  332.         case EEC_COLOR_TYPE_CG4:
  333.             whichFb = FBTYPE_SUN4COLOR;
  334.             break;
  335.         case EEC_COLOR_TYPE_CG6:
  336.             whichFb = FBTYPE_SUNFAST_COLOR;
  337.             break;
  338.         default:
  339.             ; /* just ignore... */
  340.         }
  341.         }
  342.         /* b/w display? (note: give preference to color) */
  343.         if (whichFb == -1 && eeconf->eec_un.eec_type == EEC_TYPE_BW) {
  344.         if (eeprom->ee_diag.eed_scrsize == EED_SCR_1600X1280) {
  345.             whichFb = FBTYPE_SUN2BW;
  346.             fbarray[whichFb].fb_height = 1280;
  347.             fbarray[whichFb].fb_width = 1600;
  348.             fbarray[whichFb].fb_size = 256 * 1024;
  349.         } else {
  350.             whichFb = FBTYPE_SUN2BW;
  351.         }
  352.         }
  353.     }
  354.     /* assume b/w as default */
  355.     if (whichFb == -1) {
  356.         whichFb = FBTYPE_SUN2BW;
  357.     }
  358.     if ((whichFb == FBTYPE_SUN2BW) &&
  359.         (eeprom->ee_diag.eed_scrsize == EED_SCR_1600X1280)) {
  360.         whichFb = FBTYPE_SUN2BW;
  361.         fbarray[whichFb].fb_height = 1280;
  362.         fbarray[whichFb].fb_width = 1600;
  363.         fbarray[whichFb].fb_size = 256 * 1024;
  364.     }
  365.     break;
  366.  
  367.     case SYS_DS3100:
  368.     printf("Can't do FB stuff for ds3100's yet.\n");
  369.     return FAILURE;
  370.     default:
  371.     printf("FB stuff won't handle this machine type yet.\n");
  372.     return FAILURE;
  373.     }
  374. #endif /* sun4c */
  375.  
  376.     if (whichFb < 0 || whichFb >= FBTYPE_LASTPLUSONE) {
  377.     printf("FB type is out of range.\n");
  378.     return FAILURE;
  379.     }
  380.     typePtr = &fbarray[whichFb];
  381.     devPtr->type.fb_type = typePtr->fb_type;
  382.  
  383.     devicePtr->data = (ClientData) devPtr;
  384.  
  385.     return SUCCESS;
  386. }
  387.  
  388.  
  389. /*
  390.  *----------------------------------------------------------------------
  391.  *
  392.  * DevFBIOControl --
  393.  *
  394.  *      Perform device-specific functions with the frame buffer.
  395.  *
  396.  * Results:
  397.  *      GEN_NOT_IMPLEMENTED if io control not supported.  GEN_INVALID_ARG
  398.  *    if something else went wrong.  SUCCESS otherwise, with the type
  399.  *    of the frame buffer described in the out-going buffer.
  400.  *
  401.  * Side effects:
  402.  *      None.
  403.  *
  404.  *----------------------------------------------------------------------
  405.  */
  406. /* ARGSUSED */
  407. ReturnStatus
  408. DevFBIOControl(devicePtr, ioctlPtr, replyPtr)
  409.     Fs_Device    *devicePtr;    /* Handle for device. */
  410.     Fs_IOCParam    *ioctlPtr;    /* Standard I/O Control parameter block. */
  411.     Fs_IOReply    *replyPtr;    /* Size of outBuffer and returned signal. */
  412. {
  413.     FBDevice    *devPtr;
  414.     FBType    *typePtr;
  415.  
  416.     devPtr = (FBDevice *) (devicePtr->data);
  417.  
  418.     switch (ioctlPtr->command) {
  419.     case FBIOGTYPE:
  420.     if (ioctlPtr->outBufSize < sizeof (FBType)) {
  421.         printf("Bad outbuf size.\n");
  422.         return GEN_INVALID_ARG;
  423.     }
  424.     if (devPtr->type.fb_type < 0 ||
  425.         devPtr->type.fb_type >= FBTYPE_LASTPLUSONE) {
  426.         printf("fbtype was bad.\n");
  427.         return FAILURE;
  428.     }
  429.     typePtr = &(fbarray[devPtr->type.fb_type]);
  430.     /* copy to outbuf */
  431.     devPtr->type.fb_height = typePtr->fb_height;
  432.     devPtr->type.fb_width = typePtr->fb_width;
  433.     devPtr->type.fb_depth = typePtr->fb_depth;
  434.     devPtr->type.fb_cmsize = typePtr->fb_cmsize;
  435.     devPtr->type.fb_size = typePtr->fb_size;
  436.  
  437.     bcopy((char *) &(devPtr->type), (char *) ioctlPtr->outBuffer,
  438.         sizeof (FBType));
  439.  
  440.     break;
  441. #ifdef NOTDEF
  442.     /*
  443.      * Does this ioctl really exist?  Is it used?
  444.      */
  445.     case FBIOGINFO:
  446.     if (ioctlPtr->outBufSize < sizeof (FBInfo)) {
  447.         return GEN_INVALID_ARG;
  448.     }
  449.     devPtr->info.fb_physaddr = XX;
  450.     devPtr->info.fb_hwwidth = XX;
  451.     devPtr->info.fb_hwheight = XX;
  452.     devPtr->info.fb_addrdelta = XX;
  453.     devPtr->info.fb_ropaddr = XX;
  454.     devPtr->info.fb_unit = XX;
  455.  
  456.     break;
  457. #endif /* NOTDEF */
  458.     case FBIOPUTCMAP:
  459.     if (ioctlPtr->inBufSize < sizeof (FBCMap)) {
  460.         printf("Bad inbuf size.\n");
  461.         return GEN_INVALID_ARG;
  462.     }
  463.  
  464.     if (devPtr->type.fb_type < 0 ||
  465.         devPtr->type.fb_type >= FBTYPE_LASTPLUSONE) {
  466.         printf("fbtype was bad.\n");
  467.         return FAILURE;
  468.     }
  469.     if (fbCmap == (struct colormap *) NIL) {
  470.         if (InitCmap(devPtr) != SUCCESS) {
  471.         printf("Couldn't initialize colormap.\n");
  472.         return FAILURE;
  473.         }
  474.     }
  475.  
  476.     if (PutCmap(devPtr->type.fb_type,
  477.         (FBCMap *) ioctlPtr->inBuffer) != SUCCESS) {
  478.         return FAILURE;
  479.     }
  480.  
  481.     break;
  482.  
  483.     case FBIOGETCMAP:
  484.     if (ioctlPtr->outBufSize < sizeof (FBCMap)) {
  485.         printf("Bad outbuf size.\n");
  486.         return GEN_INVALID_ARG;
  487.     }
  488.     if (devPtr->type.fb_type < 0 ||
  489.         devPtr->type.fb_type >= FBTYPE_LASTPLUSONE) {
  490.         printf("fbtype was bad.\n");
  491.         return FAILURE;
  492.     }
  493.     if (fbCmap == (struct colormap *) NIL) {
  494.         if (InitCmap(devPtr) != SUCCESS) {
  495.         printf("Couldn't initialize colormap.\n");
  496.         return FAILURE;
  497.         }
  498.     }
  499.     if (GetCmap(devPtr->type.fb_type,
  500.         (FBCMap *) ioctlPtr->outBuffer) != SUCCESS) {
  501.         return FAILURE;
  502.     }
  503.  
  504.     break;
  505.  
  506.     case FBIOSVIDEO:
  507.     if (ioctlPtr->inBufSize < sizeof (int)) {
  508.         printf("Bad inbuf size.\n");
  509.         return GEN_INVALID_ARG;
  510.     }
  511.  
  512.     if (devPtr->type.fb_type < 0 ||
  513.         devPtr->type.fb_type >= FBTYPE_LASTPLUSONE) {
  514.         printf("fbtype was bad.\n");
  515.         return FAILURE;
  516.     }
  517.  
  518.     /*
  519.      * If the display is a color display, initialize the color map first.
  520.      */
  521.     switch (devPtr->type.fb_type) {
  522.     case FBTYPE_SUN1COLOR:
  523.     case FBTYPE_SUN2COLOR:
  524.     case FBTYPE_SUN2GP:        /* color? */
  525.     case FBTYPE_SUN5COLOR:
  526.     case FBTYPE_SUN3COLOR:
  527.     case FBTYPE_MEMCOLOR:
  528.     case FBTYPE_SUN4COLOR:
  529.     case FBTYPE_SUNFAST_COLOR:
  530.     case FBTYPE_SUNROP_COLOR:
  531.     case FBTYPE_SUNFB_VIDEO:    /* color? */
  532.         if (fbCmap == (struct colormap *) NIL) {
  533.         if (InitCmap(devPtr) != SUCCESS) {
  534.             printf("Couldn't initialize colormap.\n");
  535.             return FAILURE;
  536.         }
  537.         }
  538.         break;
  539.     default:
  540.         /* Do nothing. */
  541.         break;
  542.     }
  543.  
  544.     if (SVideo(devPtr->type.fb_type,
  545.         (int *) ioctlPtr->inBuffer) != SUCCESS) {
  546.         return FAILURE;
  547.     }
  548.  
  549.     break;
  550.  
  551.     case FBIOGVIDEO:
  552.     if (ioctlPtr->outBufSize < sizeof (int)) {
  553.         printf("Bad outbuf size.\n");
  554.         return GEN_INVALID_ARG;
  555.     }
  556.  
  557.     if (devPtr->type.fb_type < 0 ||
  558.         devPtr->type.fb_type >= FBTYPE_LASTPLUSONE) {
  559.         printf("fbtype was bad.\n");
  560.         return FAILURE;
  561.     }
  562.     /*
  563.      * If the display is a color display, initialize the color map first.
  564.      */
  565.     switch (devPtr->type.fb_type) {
  566.     case FBTYPE_SUN1COLOR:
  567.     case FBTYPE_SUN2COLOR:
  568.     case FBTYPE_SUN2GP:        /* color? */
  569.     case FBTYPE_SUN5COLOR:
  570.     case FBTYPE_SUN3COLOR:
  571.     case FBTYPE_MEMCOLOR:
  572.     case FBTYPE_SUN4COLOR:
  573.     case FBTYPE_SUNFAST_COLOR:
  574.     case FBTYPE_SUNROP_COLOR:
  575.     case FBTYPE_SUNFB_VIDEO:    /* color? */
  576.         if (fbCmap == (struct colormap *) NIL) {
  577.         if (InitCmap(devPtr) != SUCCESS) {
  578.             printf("Couldn't initialize colormap.\n");
  579.             return FAILURE;
  580.         }
  581.         }
  582.         break;
  583.     default:
  584.         /* Do nothing. */
  585.         break;
  586.     }
  587.  
  588.     if (GVideo(devPtr->type.fb_type,
  589.         (int *) ioctlPtr->outBuffer) != SUCCESS) {
  590.         return FAILURE;
  591.     }
  592.     
  593.     break;
  594.  
  595.     case FBIOSATTR:
  596.     case FBIOGATTR:
  597. #ifdef NOTDEF
  598.     case FBIOGVERTICAL:
  599. #endif NOTDEF
  600.     printf("Not implemented.\n");
  601.     return GEN_NOT_IMPLEMENTED;
  602.     default:
  603.     printf("Default: invalid arg.\n");
  604.     return GEN_INVALID_ARG;
  605.     }
  606.     return SUCCESS;
  607. }
  608.  
  609.  
  610. /*
  611.  *----------------------------------------------------------------------
  612.  *
  613.  * DevFBClose --
  614.  *
  615.  *      Close the frame buffer.
  616.  *
  617.  * Results:
  618.  *      SUCCESS         - always returned.
  619.  *
  620.  * Side effects:
  621.  *      The frame buffer is "closed".
  622.  *
  623.  *----------------------------------------------------------------------
  624.  */
  625. /* ARGSUSED */
  626. ReturnStatus
  627. DevFBClose(devicePtr, useFlags, openCount, writerCount)
  628.     Fs_Device   *devicePtr;        /* Information about device. */
  629.     int         useFlags;        /* Indicates whether stream being
  630.                      * closed was for reading and/or
  631.                      * writing:  OR'ed combination of
  632.                      * FS_READ and FS_WRITE. */
  633.     int         openCount;        /* # of times this particular stream
  634.                      * is still open. */
  635.     int         writerCount;        /* # of times this particular stream
  636.                      * is still open for writing. */
  637. {
  638.     if ((openCount == 0) && (devicePtr->data != (ClientData) NIL)) { 
  639.     free((Address) devicePtr->data);
  640.     }
  641.  
  642.     return SUCCESS;
  643. }
  644.  
  645. char    searchBuffer[1024];
  646.  
  647.  
  648. /*
  649.  *----------------------------------------------------------------------
  650.  *
  651.  * CheckFBNode --
  652.  *
  653.  *    Check the frame buffer node for the information we need.
  654.  *
  655.  * Results:
  656.  *    The frame buffer type.
  657.  *
  658.  * Side effects:
  659.  *    Info about the device from the prom gets put into the fb table.
  660.  *
  661.  *----------------------------------------------------------------------
  662.  */
  663. #ifdef sun4c
  664. static int
  665. CheckFBNode(node, name)
  666.     unsigned    int        node;
  667.     char            *name;
  668. {
  669.     int        length = 0;
  670.     struct    config_ops    *configPtr;
  671.     int        i;
  672.     int        whichFb;
  673.  
  674.     configPtr = romVectorPtr->v_config_ops;
  675. #ifndef CLEAN
  676.     length = configPtr->devr_getproplen(node, "device_type");
  677.     if (length <= 0) {
  678. #ifdef DEBUG
  679.     printf("No device_type attribute found for %s.\n", name);
  680. #endif /* DEBUG */
  681.     } else {
  682.     configPtr->devr_getprop(node, "device_type", searchBuffer);
  683.     if (strcmp(searchBuffer, "display") != 0) {
  684. #ifdef DEBUG
  685.         printf("device_type for %s was not \"display\".\n", name);
  686. #endif /* DEBUG */
  687.         return 0;
  688.     }
  689.     }
  690. #endif
  691.     for (i = 0; i < FBTYPE_LASTPLUSONE; i++) {
  692.     if (strcmp(name, fbNames[i]) == 0) {
  693.         whichFb = i;
  694.         /* fill it in */
  695.         length = configPtr->devr_getproplen(node, "height");
  696.         if (length <= 0) {
  697.         printf("No height found for frame buffer in prom.\n");
  698.         } else {
  699.         configPtr->devr_getprop(node, "height", searchBuffer);
  700.         if (fbarray[i].fb_height != *(int *) searchBuffer) {
  701. #ifdef DEBUG
  702.             printf("Updating height for %s to 0x%x.\n",
  703.                 fbNames[whichFb], *(int *) searchBuffer);
  704. #endif /* DEBUG */
  705.             fbarray[i].fb_height = *(int *) searchBuffer;
  706.         }
  707.         }
  708.         length = configPtr->devr_getproplen(node, "width");
  709.         if (length <= 0) {
  710.         printf("No width found for frame buffer in prom.\n");
  711.         } else {
  712.         configPtr->devr_getprop(node, "width", searchBuffer);
  713.         if (fbarray[i].fb_width != *(int *) searchBuffer) {
  714. #ifdef DEBUG
  715.             printf("Updating width for %s to 0x%x.\n",
  716.                 fbNames[whichFb], *(int *) searchBuffer);
  717. #endif /* DEBUG */
  718.             fbarray[i].fb_width = *(int *) searchBuffer;
  719.         }
  720.         }
  721.         length = configPtr->devr_getproplen(node, "depth");
  722.         if (length <= 0) {
  723.         printf("No depth found for frame buffer in prom.\n");
  724.         } else {
  725.         configPtr->devr_getprop(node, "depth", searchBuffer);
  726.         if (fbarray[i].fb_depth != *(int *) searchBuffer) {
  727. #ifdef DEBUG
  728.             printf("Updating depth for %s to 0x%x.\n",
  729.                 fbNames[whichFb], *(int *) searchBuffer);
  730. #endif /* DEBUG */
  731.             fbarray[i].fb_depth = *(int *) searchBuffer;
  732.         }
  733.         }
  734.         length = configPtr->devr_getproplen(node, "address");
  735.         if (length <= 0) {
  736.         printf("No address found for frame buffer in prom.\n");
  737.         } else {
  738.         configPtr->devr_getprop(node, "address", searchBuffer);
  739.         if (fbaddrs[i].fb_buffer !=
  740.             (Address) (*(int *) searchBuffer)) {
  741. #ifdef DEBUG
  742.             printf("Updating address for %s to 0x%x.\n",
  743.                 fbNames[whichFb], *(int *) searchBuffer);
  744. #endif /* DEBUG */
  745.             fbaddrs[i].fb_buffer =
  746.                 (Address) (*(int *) searchBuffer);
  747.         }
  748.         }
  749.         length = configPtr->devr_getproplen(node, "reg");
  750.         if (length <= 0) {
  751.         printf("No registers found for frame buffer in prom.\n");
  752.         } else {
  753.         MachDevReg *regs;
  754.         char *phys, *virt;
  755.         int nregs, reg_offset;
  756.  
  757.         regs = (MachDevReg *)alloca(length);
  758.         nregs = length / sizeof(MachDevReg);
  759.         configPtr->devr_getprop(node, "reg", regs);
  760.         
  761.         switch (whichFb) {
  762.         case FBTYPE_SUNFAST_COLOR:
  763.             reg_offset = 0x200000;
  764.             break;
  765.         case FBTYPE_SUN2BW:
  766.         case FBTYPE_SUN3COLOR:
  767.         default:
  768.             reg_offset = 0x400000;
  769.         }
  770.  
  771.         if (romVectorPtr->v_romvec_version < 2
  772.             && regs[0].addr >= (Address)SBUS_BASE
  773.             && regs[0].bustype == 1) {    /* old style */
  774.             phys = regs[0].addr + reg_offset;
  775.         } else {                /* new style */
  776.             phys = regs[0].addr + SBUS_BASE +
  777.                regs[0].bustype * SBUS_SIZE +
  778.                reg_offset;
  779.         }
  780.         virt = VmMach_MapInDevice(phys, 1);
  781. #if 0
  782.         if (fbarray[i].fb_depth > 1 && fbaddrs[i].fb_cmap != virt) {
  783. #else
  784.         if (fbaddrs[i].fb_cmap != virt) {
  785. #endif
  786. #ifdef DEBUG
  787.             printf("Updating colormap address for %s to 0x%x.\n",
  788.                 fbNames[whichFb], virt);
  789. #endif /* DEBUG */
  790.             fbaddrs[i].fb_cmap = virt;
  791.         }
  792.         }
  793.         return whichFb;
  794.     }
  795.     }
  796.     return -1;
  797. }
  798. #endif /* sun4c */
  799.  
  800.  
  801. /*
  802.  *----------------------------------------------------------------------
  803.  *
  804.  * GetFBType --
  805.  *
  806.  *    Routine the find the frame buffer attributes from the PROM.
  807.  *
  808.  * Results:
  809.  *    Integer representing frame buffer type.
  810.  *
  811.  * Side effects:
  812.  *    None.
  813.  *
  814.  *----------------------------------------------------------------------
  815.  */
  816. #ifdef sun4c
  817. static int
  818. GetFBType()
  819. {
  820.     struct    config_ops    *configPtr;
  821.     unsigned    int        root, fb_node;
  822.     int                size;
  823.     char            *fb_type;
  824.  
  825.     configPtr = romVectorPtr->v_config_ops;
  826.     /*
  827.      * Find a frame buffer type:  First get the root node id of the tree of
  828.      * devices in the prom.  Then retrieve a pointer to the active frame
  829.      * buffer node.  Call CheckFBNode to pull all the required info from
  830.      * the PROM.
  831.      */
  832.     root = configPtr->devr_next(0);
  833.     configPtr->devr_getprop(root, "fb", &fb_node);
  834.     size = configPtr->devr_getproplen(fb_node, "name");
  835.     fb_type = (char *)alloca(size);
  836.     configPtr->devr_getprop(fb_node, "name", fb_type);
  837.  
  838.     return CheckFBNode(fb_node, fb_type);
  839. }
  840. #endif /* sun4c */
  841.  
  842.  
  843.  
  844. /*
  845.  *----------------------------------------------------------------------
  846.  *
  847.  * DevFBMMap --
  848.  *
  849.  *    Map a device into user space.
  850.  *
  851.  * Results:
  852.  *    SUCCESS or FAILURE.
  853.  *
  854.  * Side effects:
  855.  *    Device area made accessible to user.
  856.  *
  857.  *----------------------------------------------------------------------
  858.  */
  859. /*ARGSUSED*/
  860. ReturnStatus
  861. DevFBMMap(devicePtr, startAddr, length, offset, newAddrPtr)
  862.     Fs_Device    *devicePtr;
  863.     Address    startAddr;
  864.     int        length;
  865.     int        offset;
  866.     Address    *newAddrPtr;
  867. {
  868.     FBDevice    *devPtr;
  869.     Address    kernelAddr;    /* Virtual address in kernel of device. */
  870.     Address    kernelAlignedAddr;    /* Aligned virtual addr in kernel. */
  871.     int        numBytes;
  872.     ReturnStatus    status;
  873.  
  874.     devPtr = (FBDevice *) (devicePtr->data);
  875.  
  876.     kernelAddr = (Address) (fbaddrs[devPtr->type.fb_type].fb_buffer);
  877.     if (kernelAddr == (Address) NIL) {
  878.     printf("FB device has no kernel address.\n");
  879.     return FAILURE;
  880.     }
  881.     /*
  882.      * Must align user address forwards rather than backwards.  They must
  883.      * have allocated an extra segment.
  884.      */
  885.     kernelAlignedAddr = (Address)
  886.         (((unsigned int)kernelAddr) & ~(VMMACH_SEG_SIZE - 1));
  887.     numBytes = ((unsigned int)((kernelAddr + length) - kernelAlignedAddr) +
  888.         (VMMACH_SEG_SIZE - 1)) & ~(VMMACH_SEG_SIZE - 1);
  889.     status = VmMach_IntMapKernelIntoUser((unsigned int) kernelAlignedAddr,
  890.         numBytes, (unsigned int) startAddr, newAddrPtr);
  891.     if (status != SUCCESS) {
  892.     return status;
  893.     }
  894.     *newAddrPtr += (((unsigned int)kernelAddr) % VMMACH_SEG_SIZE);
  895. #ifdef DEBUG
  896.     printf("Real VA would be 0x%x\n", *newAddrPtr);
  897. #endif /* DEBUG */
  898.  
  899.     return SUCCESS;
  900. }
  901.  
  902.  
  903.  
  904. /*
  905.  *----------------------------------------------------------------------
  906.  *
  907.  * PutCmap --
  908.  *
  909.  *    Update the hardware colormap.
  910.  *
  911.  * Results:
  912.  *    SUCCESS or FAILURE.
  913.  *
  914.  * Side effects:
  915.  *    Memory updated.
  916.  *
  917.  *----------------------------------------------------------------------
  918.  */
  919. static ReturnStatus
  920. PutCmap(whichFb, cmap)
  921.     int        whichFb;
  922.     FBCMap    *cmap;
  923. {
  924.     unsigned char   *uPtr;
  925.     unsigned int    *iPtr;
  926.     int             c;
  927.     int             index = cmap->index;
  928.     int             count = cmap->count;
  929.     unsigned char   *rmap = cmap->red;
  930.     unsigned char   *gmap = cmap->green;
  931.     unsigned char   *bmap = cmap->blue;
  932.  
  933.     if(index < 0) {
  934.     printf("cmap index was < 0.\n");
  935.     return FAILURE;
  936.     }
  937.  
  938.     /* Handle colors 0..255 */
  939.     if (index >= 0 && index < 256) {
  940.     if (index+count > 256) {
  941.         count = 256 - index;
  942.     }
  943.     if (whichFb == FBTYPE_SUN4COLOR || whichFb == FBTYPE_SUN3COLOR) {
  944.         /* update the memory copy */
  945.         uPtr = &fbCmapCopy.map[index][0];
  946.         for (c = count; c != 0; --c) {
  947.         *uPtr++ = *rmap++;
  948.         *uPtr++ = *gmap++;
  949.         *uPtr++ = *bmap++;
  950.         }
  951.  
  952.         /* update DAC: weird 4/3 entries per word mapping */
  953. #define D4M3(x) ((((x)>>2)<<1) + ((x)>>2))      /* (x/4)*3 */
  954. #define D4M4(x) ((x)&~0x3)                      /* (x/4)*4 */
  955.         iPtr = &fbCmapCopy.raw[D4M3(index)];
  956.         fbCmap->addr = D4M4(index);
  957.         for (c = D4M3(index+count-1) - D4M3(index) + 3; c != 0; --c) {
  958.         fbCmap->cmap = *iPtr++;
  959.         }
  960.     } else { /* FBTYPE_SUNFAST_COLOR */
  961.         /* update the chip */
  962.         fbCmap->addr = index << 24;
  963.         for (c = count; c != 0; --c) {
  964.         fbCmap->cmap = (unsigned int)(*rmap++) << 24;
  965.         fbCmap->cmap = (unsigned int)(*gmap++) << 24;
  966.         fbCmap->cmap = (unsigned int)(*bmap++) << 24;
  967.         }
  968.     }
  969.  
  970.     /* What's left? */
  971.     index += count;
  972.     count = cmap->count-count;
  973.     }
  974.  
  975.     /* Any overlay color changes? */
  976.     if (index >= 256 && count > 0) {
  977. /******* dunno how to do that */
  978.     }
  979.     return SUCCESS;
  980. }
  981.  
  982.  
  983. /*
  984.  *----------------------------------------------------------------------
  985.  *
  986.  * GetCmap --
  987.  *
  988.  *    Return the hardware colormap.
  989.  *
  990.  * Results:
  991.  *    SUCCESS or FAILURE.
  992.  *
  993.  * Side effects:
  994.  *    Memory updated.
  995.  *
  996.  *----------------------------------------------------------------------
  997.  */
  998. static ReturnStatus
  999. GetCmap(whichFb, cmap)
  1000.     int        whichFb;
  1001.     FBCMap    *cmap;
  1002. {
  1003.     unsigned char   *uPtr;
  1004.     int             c;
  1005.     int             index = cmap->index;
  1006.     int             count = cmap->count;
  1007.     unsigned char   *rmap = cmap->red;
  1008.     unsigned char   *gmap = cmap->green;
  1009.     unsigned char   *bmap = cmap->blue;
  1010.  
  1011.     if(index < 0) {
  1012.     return FAILURE;
  1013.     }
  1014.  
  1015.     /* Handle colors 0..255 */
  1016.     if(index >= 0 && index < 256) {
  1017.     if(index+count > 256) {
  1018.         count = 256 - index;
  1019.     }
  1020.     if (whichFb == FBTYPE_SUN4COLOR || whichFb == FBTYPE_SUN3COLOR) {
  1021.         /* copy from the memory copy */
  1022.         uPtr = &fbCmapCopy.map[index][0];
  1023.         c = count;
  1024.         while(c--) {
  1025.         *rmap++ = *uPtr++;
  1026.         *gmap++ = *uPtr++;
  1027.         *bmap++ = *uPtr++;
  1028.         }
  1029.     } else { /* FBTYPE_SUNFAST_COLOR */
  1030.         /* get it from the chip */
  1031.         fbCmap->addr = index << 24;
  1032.         c = count;
  1033.         while(c--) {
  1034.         *rmap++ = (unsigned char)(fbCmap->cmap >> 24);
  1035.         *gmap++ = (unsigned char)(fbCmap->cmap >> 24);
  1036.         *bmap++ = (unsigned char)(fbCmap->cmap >> 24);
  1037.         }
  1038.     }
  1039.  
  1040.     /* What's left? */
  1041.     index += count;
  1042.     count = cmap->count-count;
  1043.     }
  1044.  
  1045.     /* Any overlay color requested? */
  1046.     if(index >= 256 && count > 0) {
  1047. /******* dunno how to do that */
  1048.     }
  1049.  
  1050.     return SUCCESS;
  1051. }
  1052.  
  1053. /*
  1054.  *----------------------------------------------------------------------
  1055.  *
  1056.  * SVideo --
  1057.  *
  1058.  *    Turn on or off the video.
  1059.  *
  1060.  * Results:
  1061.  *    SUCCESS or FAILURE.
  1062.  *
  1063.  * Side effects:
  1064.  *    Video turned on or off.
  1065.  *
  1066.  *----------------------------------------------------------------------
  1067.  */
  1068. static ReturnStatus
  1069. SVideo(whichFb, statePtr)
  1070.     int        whichFb;
  1071.     int        *statePtr;
  1072. {
  1073.     int        onOff;
  1074.  
  1075.     onOff = *statePtr;
  1076.     switch (whichFb) {
  1077.     case FBTYPE_SUN2BW:
  1078.     case FBTYPE_SUN3COLOR:
  1079.     /* this works for some color frame buffers too. -dl */
  1080.     if (fbaddrs[whichFb].fb_cmap != (void *)NIL) {
  1081.         if (onOff) {
  1082.         *(unsigned char *)(fbaddrs[whichFb].fb_cmap + 0x10) |= 0x40;
  1083.         } else {
  1084.         *(unsigned char *)(fbaddrs[whichFb].fb_cmap + 0x10) &= ~0x40;
  1085.         }
  1086.     }
  1087.     return SUCCESS;
  1088.     case FBTYPE_SUN4COLOR:
  1089.     case FBTYPE_SUNFAST_COLOR:
  1090.     /* get colormap access */
  1091.     if(fbCmap == (struct colormap *) NIL) {
  1092.         printf("Colormap not yet set.\n");
  1093.         return FAILURE;
  1094.     }
  1095.  
  1096.     /* Twiddle command registers to turn video off */
  1097.     if (onOff) {
  1098.          onOff = ~0;
  1099.     }
  1100.     if(whichFb == FBTYPE_SUNFAST_COLOR) {
  1101.         fbCmap->addr = 0x04 << 24;      /* read mask */
  1102.         fbCmap->ctrl = onOff;           /* color planes */
  1103.     } else {
  1104.         /* overlay off for blanking */
  1105.         fbCmap->addr = 0x06;            /* command reg */
  1106.         fbCmap->ctrl = 0x70|(onOff&3);  /* overlay plane */
  1107.         /* read mask off for blanking */
  1108.         fbCmap->addr = 0x04;            /* read mask */
  1109.         fbCmap->ctrl = onOff;           /* color planes */
  1110.         if(!onOff) {
  1111.         /* color 0 -> black for blanking */
  1112.         fbCmap->addr = 0x00;
  1113.         fbCmap->cmap = 0x00000000;
  1114.         } else {
  1115.         /* restore colors */
  1116.         fbCmap->addr = 0x00;
  1117.         fbCmap->cmap = fbCmapCopy.raw[0];
  1118.         fbCmap->cmap = fbCmapCopy.raw[1];
  1119.         fbCmap->cmap = fbCmapCopy.raw[2];
  1120.         }
  1121.     }
  1122.     return SUCCESS;
  1123.     default:
  1124.     return FAILURE;
  1125.     }
  1126. }
  1127.  
  1128. /*
  1129.  *----------------------------------------------------------------------
  1130.  *
  1131.  * GVideo --
  1132.  *
  1133.  *    Get the on/off status of the video.
  1134.  *
  1135.  * Results:
  1136.  *    SUCCESS or FAILURE.
  1137.  *
  1138.  * Side effects:
  1139.  *    Video status returned in out parameter.
  1140.  *
  1141.  *----------------------------------------------------------------------
  1142.  */
  1143. static ReturnStatus
  1144. GVideo(whichFb, statePtr)
  1145.     int        whichFb;
  1146.     int        *statePtr;
  1147. {
  1148.     int        rmask;
  1149.  
  1150.     switch (whichFb) {
  1151.     case FBTYPE_SUN2BW:
  1152.     case FBTYPE_SUN3COLOR:
  1153.     if (fbaddrs[whichFb].fb_cmap != (void *)NIL) {
  1154.         rmask = *(unsigned char *)(fbaddrs[whichFb].fb_cmap + 0x10);
  1155.         *statePtr = (rmask & 0x40) ? 1 : 0;
  1156.     }
  1157.     return SUCCESS;
  1158.     case FBTYPE_SUN4COLOR:
  1159.     case FBTYPE_SUNFAST_COLOR:
  1160.     /* get colormap access */
  1161.     if(fbCmap == (struct colormap *) NIL) {
  1162.         printf("Colormap not yet set.\n");
  1163.         return FAILURE;
  1164.     }
  1165.     /* Look hard at the control registers */
  1166.     if(whichFb == FBTYPE_SUNFAST_COLOR) {
  1167.         fbCmap->addr = 0x04 << 24;      /* read mask */
  1168.         rmask = fbCmap->ctrl >> 24;     /* color planes */
  1169.     } else {
  1170.         fbCmap->addr = 0x04;            /* read mask */
  1171.         rmask = fbCmap->ctrl;           /* color planes */
  1172.     }
  1173.     *statePtr = (rmask & 0xff) ? 1 : 0;
  1174.     break;
  1175.     default:
  1176.     return FAILURE;
  1177.     }
  1178.     return SUCCESS;
  1179. }
  1180.  
  1181. /*
  1182.  *----------------------------------------------------------------------
  1183.  *
  1184.  * InitCmap --
  1185.  *
  1186.  *    Initialize the colormap.
  1187.  *
  1188.  * Results:
  1189.  *    SUCCESS or FAILURE.
  1190.  *
  1191.  * Side effects:
  1192.  *    Colormap data structures initialized.
  1193.  *
  1194.  *----------------------------------------------------------------------
  1195.  */
  1196. static ReturnStatus
  1197. InitCmap(devPtr)
  1198.     FBDevice    *devPtr;
  1199. {
  1200.     int        c;
  1201.     int        whichFb;
  1202.  
  1203.     whichFb = devPtr->type.fb_type;
  1204.     fbCmap = fbaddrs[whichFb].fb_cmap;
  1205.  
  1206.     if ((whichFb != FBTYPE_SUN4COLOR) && (whichFb != FBTYPE_SUNFAST_COLOR) &&
  1207.         (whichFb != FBTYPE_SUN3COLOR)) {
  1208.     printf("Wrong fb type to have a colormap.\n");
  1209.     return FAILURE;
  1210.     }
  1211.     /* Init colormap copy, overlay, etc.. */
  1212.     if(whichFb == FBTYPE_SUNFAST_COLOR) {
  1213.     fbCmap->addr = 0x06 << 24;      /* command register address */
  1214.     fbCmap->ctrl = 0x70 << 24;      /* disable cursor overlay */
  1215.     } else {
  1216.     for (c = 0; c < 256 * 3 / 4; c++) {
  1217.         fbCmapCopy.raw[c] = fbCmap->cmap;
  1218.     }
  1219.     fbCmap->addr = 0x06;            /* command register address */
  1220.     fbCmap->ctrl = 0x73;            /* enable overlay */
  1221.     /* set overlay colors: bg: blue, fg: white */
  1222.     fbCmap->addr = 0x00;
  1223.     fbCmap->omap = 0x00000000;
  1224.     fbCmap->omap = 0x00ff0000;
  1225.     fbCmap->omap = 0x00ffffff;
  1226.     }
  1227.  
  1228.     return SUCCESS;
  1229. }
  1230.